#coding:utf-8


"""
@auth  lijw
#文件夹
#列表文件
#获取文件总大小
#获取磁盘剩余空间
同步
同步成功发消息
1,检查是否已经同步过
2,超时处理       2017年8月10日 16:57:15
3,统计文件数/总文件数  统计大小/总大小   脚本结束后,上报数据    
4,检查只读文件系统
"""

import os,sys,getopt
import logging
import arrow,time
import MySQLdb
import re
from subprocess import Popen,PIPE,STDOUT
import requests
import psutil

ydt=arrow.now().replace(hours=-24).format('YYYY-MM-DD')

work_dir="/home/jobs/rsynclog/"
mysql_host="192.168.1.28"
mysql_user="root"
mysql_password="work"
mysql_db="work"

timeout=120
def human_readable(plain_size):
     plain_size = float(plain_size)
     if plain_size <= 1024:
         return str( round(plain_size, 2)) + 'B'
     if plain_size <= 1024 * 1024:
         return str( round(plain_size / 1024, 2)) + 'K'
     if plain_size <= 1024 * 1024 * 1024:
         return str( round(plain_size / 1024 / 1024, 2)) + 'M'
     else:
         return str( round(plain_size / 1024 / 1024 / 1024, 2)) + 'G'

def sendmessage(msg):
    m=requests.get("http://192.168.1.28:9999/im",params={'touser': 'lijw_win7', 'message':tolog+msg}, timeout=3)
    logging.info("发送消息"+tolog+msg)


class rsynclog(object):


    def __init__(self,logmod):
        self.logmod=logmod
        self.yqmod,self.tr_dir,self.udisk=self.SetInit()
        self.needsize=""
        self.syncfile=work_dir+"/log/"+self.yqmod+str(ydt)
        self.filecount=0
    def SetInit(self):
        global mysql_host,mysql_user,mysql_password,mysql_db
        try:
            mysql_h = MySQLdb.connect(host=mysql_host, user=mysql_user, passwd=mysql_password, db=mysql_db)
            mysql_cur = mysql_h.cursor()
            sql = "select concat(yq_ip,\"::\",yq_name) yqmod,tr_dir,udisk from logcollect where logname=\"" + self.logmod + "\""
            mysql_cur.execute(sql)
            for row in mysql_cur.fetchall():
                yqmod  = row[0]
                tr_dir = row[1]
                udisk  = row[2]
            mysql_h.close()
            return yqmod,tr_dir,udisk
        except Exception,e:
            print "mysql 链接出错 %s " % e
            return False,False,False

    def get_sync_filelist(self):
        #linelist=os.popen("rsync -r "+self.logmod+" |grep "+str(ydt)).readlines()
        logging.info("rsync -r "+self.yqmod+" |grep "+str(ydt))
        p = Popen("/usr/bin/rsync -r "+self.yqmod+" |grep "+str(ydt), shell=True, stdout=PIPE, stdin=PIPE,stderr=STDOUT)
        t_beginning = time.time()
        seconds_passed = 0
        while True:
            if p.poll() is not None:
                break
            seconds_passed = time.time() - t_beginning
            if timeout and seconds_passed > timeout:
                linelist = p.stdout.readlines()
                if len(linelist) > 10:
                    logging.info("超时判定,但标准输出有内容,仍继续同步")
                    filesize = []
                    filelist = []
                    for line in linelist:
                        filesize.append(int(re.split(r"[\s]", re.sub(r"\s{2,}", " ", line))[1]))
                        filelist.append(re.split(r"[\s]", re.sub(r"\s{2,}", " ", line))[4])
                    self.needsize = int(sum(filesize))
                    self.filecount = len(filelist) + 1
                    logging.info(self.needsize)
                    f = open(self.syncfile, "w")
                    try:
                        for line in filelist:
                            f.write(line + "\n")
                    finally:
                        f.close()
                    return 1 #超时为异常,依然然同步
                p.terminate()
                logging.info("获取同步文件,已经超时"+str(timeout)+"s")
                return 2  #超时
            time.sleep(0.1)
        p.wait()
        linelist=p.stdout.readlines()
        filesize=[]
        filelist=[]
        for line in linelist:
            filesize.append(int(re.split(r"[\s]",re.sub(r"\s{2,}"," ",line))[1]))
            filelist.append(re.split(r"[\s]",re.sub(r"\s{2,}"," ",line))[4])
        self.needsize=int(sum(filesize))
        self.filecount=len(filelist)+1
        logging.info( self.needsize)
        f=open(self.syncfile,"w")
        try:
            for line in filelist:
                f.write(line+"\n")
        finally:
            f.close()
        return 0
   # def do_sync(self):
    def do_sync(self):
        free_size=psutil.disk_usage(self.tr_dir).free
        if self.needsize > free_size:
            logging.info("同步文件数"+str(self.filecount)+"磁盘剩余空间不够,需要磁盘空间" + human_readable(self.needsize) + " 剩余空间" + human_readable(free_size))
            return 1
        logging.info("同步文件数"+str(self.filecount)+"需要磁盘空间" + human_readable(self.needsize) + " 剩余空间" + human_readable(free_size))
        logging.info("开始同步")
        p = Popen("rsync -avz " + self.yqmod + " --files-from=" +self.syncfile+" "+self.tr_dir, shell=True, stdout=PIPE, stdin=PIPE)
        p.wait()
        logging.info("同步完成")
        return 0

    def rep2mysql(self):
        global mysql_host, mysql_user, mysql_password, mysql_db
        try:
            mysql_h = MySQLdb.connect(host=mysql_host, user=mysql_user, passwd=mysql_password, db=mysql_db)
            mysql_cur = mysql_h.cursor()
            sql = "insert into everyday_log_syncsize(logmod,filecount,size,date_time) values(\""+\
                  self.logmod+"\","+\
                  str(self.filecount)+","+\
                  str(self.needsize) +",\""+\
                  str(ydt)+"\")"
            logging.info(sql)
            n=mysql_cur.execute(sql)
            logging.info(n)
            mysql_cur.close()
            mysql_h.close()
        except Exception, e:
            logging.info("mysql 链接出错 ")
            logging.info(e)
    def check_disk_readonly(self):
        os.chdir(self.tr_dir)
        try:
            f=open("readonly.txt","w")
            f.close()
        except IOError,e:
            if e.errno==30:
                logging.info("发现只读文件系统,无法写入")
                return 1
            else:
                return 0



###在这里开始
logging.basicConfig(level=logging.DEBUG,
                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                datefmt='%a, %d %b %Y %H:%M:%S',
                filename='logsync.log',
                )
opts, args = getopt.getopt(sys.argv[1:], "l:")
for op, value in opts:
    if op == "-i":
        tolog=value
    elif op=="-h":
        sys.exit()

tolog=sys.argv[1]
if __name__=="__main__":

    r=rsynclog(tolog)
    logging.info("等待同步日志"+tolog)
    logging.info(str(r.yqmod)+ str(r.tr_dir)+str(r.udisk))
    if  r.get_sync_filelist()==2:               #rsync异常
        sendmessage("同步出错")
    elif r.check_disk_readonly()==1:
        sendmessage("只读文件系统")
    else:
        if r.do_sync()==0:
            sendmessage("同步完成")
            r.rep2mysql()



